package com.talent.service.iot.mqtt.server;


import com.talent.service.iot.mqtt.codec.decoder.*;
import com.talent.service.iot.mqtt.codec.encoder.*;
import com.talent.service.iot.mqtt.handler.*;

import com.talent.service.iot.mqtt.config.TlMqttProperties;
import com.talent.service.iot.mqtt.config.TlPortProperties;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;


import javax.annotation.PostConstruct;

/**
 * @ClassName：Server
 * @Author: hszhou
 * @Date: 2024/11/15 15:10
 * @Description: 启动类
 */
@Component
public class TlMqttServer {

    private static final  Logger logger = LoggerFactory.getLogger(TlMqttServer.class);


    private final TlMqttConnectHandler mqttConnectHandler;

    private final TlMqttPublishHandler mqttPublishHandler;

    private final TlMqttSubScribeHandler mqttSubScribeHandler ;

    private final TlMqttUnSubScribeHandler mqttUnSubScribeHandler ;

    private final TlMqttHeartBeatHandler mqttHeartBeatHandler ;

    private final TlMqttDisconnectHandler mqttDisconnectHandler;

    private final TlMqttPubCompHandler mqttPubCompHandler;

    private final TlMqttPubAckHandler mqttPubAckHandler;

    private final TlMqttPubRecHandler mqttPubRecHandler ;

    private final TlMqttPubRelHandler mqttPubRelHandler ;

    private final TlMqttConnackEncoder mqttConnackEncoder ;

    private final TlMqttHeaderBeatEncoder mqttHeaderBeatEncoder;

    private final TlMqttSubAckEncoder mqttSubAckEncoder ;

    private final TlMqttUnSubAckEncoder mqttUnSubAckEncoder;

    private final TlMqttPublishEncoder mqttPublishEncoder;

    private final TlMqttPubAckEncoder mqttPubAckEncoder;

    private final TlMqttPubRecEncoder mqttPubRecEncoder;

    private final TlMqttPubRelEncoder mqttPubRelEncoder;

    private final  TlMqttPubCompEncoder mqttPubCompEncoder;

    private final TlMqttExceptionHandler mqttExceptionHandler ;

    private final HeartbeatEventTriggered heartbeatEventTriggered;

    private final TlMqttConnectDecoder connectDecoder;

    private final  TlMqttDisConnectDecoder disConnectDecoder;

    private final  TlMqttHeartBeatDecoder heartBeatDecoder;

    private final  TlMqttPubAckDecoder pubAckDecoder;

    private final TlMqttPubCompDecoder pubCompDecoder;

    private final TlMqttPublishDecoder publishDecoder;

    private final  TlMqttPubRecDecoder pubRecDecoder;

    private final TlMqttPubRelDecoder pubRelDecoder;

    private final  TlMqttSubscribeDecoder subscribeDecoder;

    private final TlMqttUnSubscribeDecoder unSubscribeDecoder;

    private  final TlMqttProperties mqttConfig;



    public TlMqttServer(TlMqttConnectHandler mqttConnectHandler,
                        TlMqttPublishHandler mqttPublishHandler,
                        TlMqttSubScribeHandler mqttSubScribeHandler,
                        TlMqttUnSubScribeHandler mqttUnSubScribeHandler,
                        TlMqttHeartBeatHandler mqttHeartBeatHandler,
                        TlMqttDisconnectHandler mqttDisconnectHandler,
                        TlMqttPubCompHandler mqttPubCompHandler,
                        TlMqttPubAckHandler mqttPubAckHandler,
                        TlMqttPubRecHandler mqttPubRecHandler,
                        TlMqttPubRelHandler mqttPubRelHandler,
                        TlMqttConnackEncoder mqttConnackEncoder,
                        TlMqttHeaderBeatEncoder mqttHeaderBeatEncoder,
                        TlMqttSubAckEncoder mqttSubAckEncoder,
                        TlMqttUnSubAckEncoder mqttUnSubAckEncoder,
                        TlMqttPublishEncoder mqttPublishEncoder,
                        TlMqttPubAckEncoder mqttPubAckEncoder,
                        TlMqttPubRecEncoder mqttPubRecEncoder,
                        TlMqttPubRelEncoder mqttPubRelEncoder,
                        TlMqttPubCompEncoder mqttPubCompEncoder,
                        TlMqttExceptionHandler mqttExceptionHandler,
                        HeartbeatEventTriggered heartbeatEventTriggered,
                        TlMqttConnectDecoder connectDecoder,
                        TlMqttDisConnectDecoder disConnectDecoder,
                        TlMqttHeartBeatDecoder heartBeatDecoder,
                        TlMqttPubAckDecoder pubAckDecoder,
                        TlMqttPubCompDecoder pubCompDecoder,
                        TlMqttPublishDecoder publishDecoder,
                        TlMqttPubRecDecoder pubRecDecoder,
                        TlMqttPubRelDecoder pubRelDecoder,
                        TlMqttSubscribeDecoder subscribeDecoder,
                        TlMqttUnSubscribeDecoder unSubscribeDecoder,
                        TlMqttProperties mqttConfig) {
        this.mqttConnectHandler = mqttConnectHandler;
        this.mqttPublishHandler = mqttPublishHandler;
        this.mqttSubScribeHandler = mqttSubScribeHandler;
        this.mqttUnSubScribeHandler = mqttUnSubScribeHandler;
        this.mqttHeartBeatHandler = mqttHeartBeatHandler;
        this.mqttDisconnectHandler = mqttDisconnectHandler;
        this.mqttPubCompHandler = mqttPubCompHandler;
        this.mqttPubAckHandler = mqttPubAckHandler;
        this.mqttPubRecHandler = mqttPubRecHandler;
        this.mqttPubRelHandler = mqttPubRelHandler;
        this.mqttConnackEncoder = mqttConnackEncoder;
        this.mqttHeaderBeatEncoder = mqttHeaderBeatEncoder;
        this.mqttSubAckEncoder = mqttSubAckEncoder;
        this.mqttUnSubAckEncoder = mqttUnSubAckEncoder;
        this.mqttPublishEncoder = mqttPublishEncoder;
        this.mqttPubAckEncoder = mqttPubAckEncoder;
        this.mqttPubRecEncoder = mqttPubRecEncoder;
        this.mqttPubRelEncoder = mqttPubRelEncoder;
        this.mqttPubCompEncoder = mqttPubCompEncoder;
        this.mqttExceptionHandler = mqttExceptionHandler;
        this.heartbeatEventTriggered = heartbeatEventTriggered;
        this.connectDecoder = connectDecoder;
        this.disConnectDecoder = disConnectDecoder;
        this.heartBeatDecoder = heartBeatDecoder;
        this.pubAckDecoder = pubAckDecoder;
        this.pubCompDecoder = pubCompDecoder;
        this.publishDecoder = publishDecoder;
        this.pubRecDecoder = pubRecDecoder;
        this.pubRelDecoder = pubRelDecoder;
        this.subscribeDecoder = subscribeDecoder;
        this.unSubscribeDecoder = unSubscribeDecoder;
        this.mqttConfig = mqttConfig;
    }

    @PostConstruct
    public void start(){

        NioEventLoopGroup work = new NioEventLoopGroup();
        NioEventLoopGroup boss = new NioEventLoopGroup();
        ServerBootstrap bootstrap = new ServerBootstrap();

        try {
            bootstrap.group(boss,work)
            .option(ChannelOption.SO_BACKLOG,1024)
            .option(ChannelOption.SO_REUSEADDR,true)
             .childOption(ChannelOption.SO_KEEPALIVE,true)
             .childOption(ChannelOption.TCP_NODELAY,true)
             .childOption(ChannelOption.SO_SNDBUF,32*1024)
                    .childOption(ChannelOption.SO_RCVBUF,32*1024)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new TlMqttChannelInitializer(
                            mqttConnectHandler,
                            mqttPublishHandler,
                            mqttSubScribeHandler,
                            mqttUnSubScribeHandler,
                            mqttHeartBeatHandler,
                            mqttDisconnectHandler,
                            mqttPubCompHandler,
                            mqttPubAckHandler,
                            mqttPubRecHandler,
                            mqttPubRelHandler,
                            mqttConnackEncoder,
                            mqttHeaderBeatEncoder,
                            mqttSubAckEncoder,
                            mqttUnSubAckEncoder,
                            mqttPublishEncoder,
                            mqttPubAckEncoder,
                            mqttPubRecEncoder,
                            mqttPubRelEncoder,
                            mqttPubCompEncoder,
                            mqttExceptionHandler,
                            heartbeatEventTriggered,
                            connectDecoder,disConnectDecoder,heartBeatDecoder,
                            pubAckDecoder,pubCompDecoder,publishDecoder,pubRecDecoder,pubRelDecoder,
                            subscribeDecoder,unSubscribeDecoder));
            TlPortProperties portConfig = mqttConfig.getPort();
            int port = portConfig.getMqtt();
            ChannelFuture channelFuture = bootstrap.bind(port).sync();
            logger.info("mqtt server start success port is {}",port);
            channelFuture.channel().closeFuture().addListener(r->{
                work.shutdownGracefully();
                boss.shutdownGracefully();
            });
        }catch (Exception e){
            e.printStackTrace();
            logger.error("出现异常");
        }
    }
}
